<?php

class Kd_Collection_List extends Kd_Collection_Enumerator
               implements ArrayAccess, SeekableIterator, Serializable, Countable {

    public function __construct($source = array()){
        parent::__construct($source);
    }

    public function getItem($offset){
        return $this->source[$offset];
    }

    public function getFirstItem(){
        $this->rewind();
        return current($this->source);
    }

    public function getLastItem(){
        return end($this->source);
    }

    public function append($item, $offset = NULL){
        if($offset === NULL){
            $this->source[] = $item;
        }else{
            $this->source[$offset] = $item;
        }

        return $this;
    }

    public function remove($offset){
        unset($this->source[$offset]);
        return $this;
    }

    public function clear(){
        $this->source = array();
        return $this;
    }

    public function merge(array $arr){
        array_merge($this->source, $arr);
        return $this;
    }

    public function isEmpty(){
        return count($this->source) == 0;
    }

    public function join($str){
        return implode($str, $this->source);
    }

    public function toArray(){
        $result = array();
        foreach($this as $item){
            if(is_object($item)){
                $result[] = method_exists($item, 'toArray')? $item->toArray(): $item;
            }else{
                $result[] = $item;
            }
        }
        return $result;
    }

    public function count() {
        return count($this->source);
    }

    public function offsetExists($offset) {
        return isset($this->source[$offset]);
    }

    public function offsetGet($offset) {
        return $this->getItem($offset);
    }

    public function offsetSet($offset, $value) {
        $this->append($value, $offset);
    }

    public function offsetUnset($offset) {
        unset($this->source[$offset]);
    }

    public function seek($position) {
        throw new Kd_Exception('The seek method not support');
    }

    public function serialize() {
        return serialize($this->source);
    }

    public function unserialize($serialized) {
        $arr = unserialize($serialized);
        return new self($arr);
    }
}